<?php

namespace App\Repositories\Eloquent;

use App\Repositories\Contracts\ApiRepositoryInterface;
use App\Repositories\Contracts\RepositoryInterface;
use Illuminate\Container\Container as App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Validator;

/**
 * Repository 抽象类
 *
 * Class Repository
 * @package App\Repositories\Eloquent
 */
abstract class Repository implements RepositoryInterface, ApiRepositoryInterface
{
    private $app;
    protected $model;
    protected $statusCode = 200;

    /**
     * 依赖注入 Container与创建模型
     *
     * Repository constructor.
     * @param $app
     */
    public function __construct(App $app)
    {
        $this->app = $app;

        $this->makeModel();
    }

    /**
     * 指定模型名称
     *
     * @return mixed
     */
    abstract public function model();

    /**
     * 根据模型名创建Eloquent ORM 实例
     *
     * @return bool|\Illuminate\Database\Eloquent\Builder
     */
    public function makeModel()
    {
        $model = $this->app->make($this->model());
        if (!$model instanceof Model) {
            return false;
        }
        return $this->model = $model;
    }

    /*
    |--------------------------------------------------------------------------
    | 数据库相关
    |--------------------------------------------------------------------------
    |
    | 含有数据库的CRUD操作,分页等
    |
    |
    */

    /**
     * 根据主键查找数据
     *
     * @param $id
     * @param array $columns
     * @return mixed
     */
    public function find($id, $columns = array('*'))
    {
        return $this->model->find($id, $columns);
    }

    /**
     * 根据指定键与值查找数据
     *
     * @param $attribute
     * @param $value
     * @param array $columns
     * @return mixed
     */
    public function findBy($attribute, $value, $columns = array('*'))
    {
        return $this->model->where($attribute, $value)->first($columns);
    }

    /**
     * 获取所有数据
     *
     * @param array $columns
     * @return mixed
     */
    public function all($columns = array('*'))
    {
        return $this->model->get($columns);
    }

    /**
     * 预加载
     *
     * @param $relations
     * @return mixed
     */
    public function with($relations)
    {
        return $this->model->with(is_string($relations) ? func_get_args() : $relations);
    }

    /**
     * 批量创建
     *
     * @param array $data
     * @return mixed
     */
    public function create(array $data)
    {
        return $this->model->create($data);
    }

    /**
     * 根据主键更新
     *
     * @param array $data
     * @param $id
     * @param string $attribute
     * @return mixed
     */
    public function update(array $data, $id, $attribute = 'id')
    {
        return $this->model->where($attribute, '=', $id)->update($data);
    }

    /**
     * 根据主键删除数据
     *
     * @param $ids
     * @return mixed
     */
    public function delete($ids)
    {
        return $this->model->destroy($ids);
    }

    /**
     * 获取分页数据
     *
     * @param int $perPage
     * @param array $columns
     * @return mixed
     */
    public function paginate($perPage = 10, $columns = array('*'))
    {
        return $this->model->paginate($perPage, $columns);
    }


    /**
     * 日期范围参数设置,全局公用
     * @param  [type] $request [description]
     * @return [type]          [description]
     */
    public function range($request, $type = null)
    {
        $none = array();

        $today = strtotime(date("Y-m-d", time()));

        switch ($type) {
            case 'reg':
                if (!isset($request->regdate_begin) || !isset($request->regdate_end)) {
                    return $none;
                } else {                    
                    $begin = strtotime($request->regdate_begin);
                    $end = strtotime($request->regdate_end);
                    if($begin == $today && $end == $today)
                        return $none;
                }
                break;

            case 'fee':
                if (!isset($request->feedate_begin) || !isset($request->feedate_end)) {
                    return $none;
                } else {
                    $begin = strtotime($request->feedate_begin);
                    $end = strtotime($request->feedate_end);
                    if($begin == $today && $end == $today)
                        return $none;
                }
                break;
            
            default:
                if (!isset($request->date_begin) || !isset($request->date_end)) {
                    $begin = $today;
                    $end = $begin + 86400 - 1;
                } else {
                    $begin = strtotime($request->date_begin);
                    $end = strtotime($request->date_end);
                }
                break;
        }
        

        if ($begin == $end) {
            $end = $begin + 86400 - 1 ;
        } else {
            $end = $end + 86400 - 1;
        }
        
        return array($begin, $end);
    }
    
    /*
    |--------------------------------------------------------------------------
    | 响应处理
    |--------------------------------------------------------------------------
    |
    |
    |
    |
    */
    public function responseEncode($status, $message = '', $data = [], $url = null)
    {
        $result = [
            'status'     => boolval($status),
            'code'       => intval($this->statusCode),
            'message'    => strval($message),
            'data'       => isset($data) ? $data : (object)array(),
            'url'        => $url,
        ];
        
        return response()->json($result, $this->statusCode);
    }

    public function responseSuccess($message = '', $data = [], $url = null)
    {
        $message = $message ? $message : 'success';

        return $this->responseEncode(true, $message, $data, $url);
    }


    public function responseFail($errorCode, $message = '', $data = [], $url = null)
    {
        $this->statusCode = $errorCode;

        $message = $message ? $message : 'failed';

        return $this->responseEncode(false, $message, $data, $url);
    }


   
    /*
    |--------------------------------------------------------------------------
    | API相关
    |--------------------------------------------------------------------------
    |
    |
    |
    |
    */

    /**
     * 获取状态码
     *
     * @return int
     */
    public function getStatusCode()
    {
        return $this->statusCode;
    }

    /**
     * 设置状态码
     *
     * @param $statusCode
     * @return $this
     */
    public function setStatusCode($statusCode)
    {
        $this->statusCode = $statusCode;
        return $this;
    }

    
    /**
     * 自定义验证数据
     *
     * @param Request $request
     * @param array $rules
     * @param array $messages
     * @param array $customAttributes
     * @return mixed|void
     */
    public function validate(Request $request, array $rules, array $messages = [], array $customAttributes = [])
    {
        Validator::make($request->all(), $rules, $messages, $customAttributes)->validate();
    }

    
    public function transformMethod($method)
    {
        $result = 0;

        switch ($method) {
            case 'study':
                $result = PLAN_TYPE_STUDY;
                break;
            case 'science':
                $result = PLAN_TYPE_SCIENCE;
                break;
            case 'baby':
                $result = PLAN_TYPE_BABY;
                break;
            default:
                break;
        }

        return $result;
    }


    public function transformType($type)
    {
        $result = '';

        switch ($type) {
            case PLAN_TYPE_STUDY:
                $result = 'study';
                break;
            case PLAN_TYPE_SCIENCE:
                $result = 'science';
                break;
            case PLAN_TYPE_BABY:
                $result = 'baby';
                break;
            default:
                break;
        }

        return $result;
    }


    public function transformTitle($type)
    {
        $result = 0;

        switch ($type) {
            case PLAN_TYPE_STUDY:
                $result = '公益培训';
                break;
            case PLAN_TYPE_SCIENCE:
                $result = '科普课堂';
                break;
            case PLAN_TYPE_BABY:
                $result = '育婴培训';
                break;
            default:
                break;
        }

        return $result;
    }
}
